home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Programming / QuakeTools / src / libqtools / bsp.c next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  23.3 KB  |  748 lines

  1. #define    LIBQTOOLS_CORE
  2. #include "../include/libqtools.h"
  3. #include "../include/libqbuild.h"
  4.  
  5. /* light */
  6. bool waterlit = FALSE;
  7. float scale = 0, range = 0;
  8. /* qbsp */
  9. bool watervis = FALSE, slimevis = FALSE;
  10. bool nofill = FALSE, notjunc = FALSE, noclip = FALSE, onlyents = FALSE, usehulls = FALSE;
  11. int subdivide = 0, hullnum = 0;
  12. /* vis */
  13. bool fastvis = FALSE;
  14. int vislevel = 2;
  15.  
  16. bool AddBSP(struct palpic *inPic, struct rawdata *inData, char *bspName, operation procOper, filetype inType)
  17. {
  18.   bool retval = FALSE;
  19.   bool appendPic = FALSE;
  20.   char *procName = 0;
  21.   char *srcName;
  22.   FILE *bspFile = 0;
  23.   __memBase = 0;
  24.  
  25. #ifdef    MEM_SIZETRACK
  26.   mprintf(" memory  :        %7i (       %7i)\n", memcounter, mempeak);
  27. #ifdef    MEM_ANALYSE
  28.   mprintf("                  %7i (       %7i)\n", memallocs, mempeakallocs);
  29.   mprintf("                  %7i (       %7i)\n", memcounter/memallocs, mempeak/mempeakallocs);
  30. #endif
  31. #endif
  32.  
  33.   if (inPic) {
  34.     procName = inPic->name;
  35.     appendPic = TRUE;
  36.   }
  37.   else if (inData) {
  38.     procName = inData->name;
  39.     appendPic = FALSE;
  40.   }
  41.   srcName = GetExt(procName);
  42.  
  43.   if (!strcmp(srcName, "wad") || (inType == TYPE_WAD2))
  44.     appendPic = TRUE;
  45.  
  46.   if (appendPic == TRUE) {
  47.   }
  48.   else {
  49.     bool newBsp = FALSE, newLit = FALSE, newVis = FALSE;
  50.     bool oldBsp = FALSE, oldLit = FALSE, oldVis = FALSE;
  51.  
  52.     if (!strcmp(srcName, "map") || (inType == TYPE_MAP)) {
  53.       newBsp = TRUE;
  54.       inType = TYPE_MAP;
  55.     }
  56.     else if (!strcmp(srcName, "iob") || (inType == TYPE_IMAGINE)) {
  57.       newBsp = TRUE;
  58.       inType = TYPE_IMAGINE;
  59.     }
  60.     else if (!strcmp(srcName, "prt") || (inType == TYPE_PRT)) {
  61.       newVis = TRUE;
  62.       inType = TYPE_PRT;
  63.     }
  64.     else if (!strcmp(srcName, "vis") || (inType == TYPE_VIS)) {
  65.       oldVis = oldBsp = TRUE;
  66.       inType = TYPE_VIS;
  67.     }
  68.     else if (!strcmp(srcName, "lit") || (inType == TYPE_LIT)) {
  69.       oldLit = oldBsp = TRUE;
  70.       inType = TYPE_LIT;
  71.     }
  72.     else if (inType == TYPE_LIT) {
  73.       newLit = TRUE;
  74.       inType = TYPE_LIT;
  75.     }
  76.  
  77.     while (1) {
  78.       if (!setjmp(eabort)) {
  79.     if (oldBsp == TRUE) {
  80.       if (!(bspFile = fopen(bspName, READWRITE_BINARY_OLD))) {
  81.         eprintf("failed to open file %s\n", bspName);
  82.         break;
  83.       }
  84.       if (!(bspMem = LoadBSP(bspFile, ALL_LUMPS))) {
  85.         eprintf("failed to load file %s\n", bspName);
  86.         break;
  87.       }
  88.       
  89.       bspMem->bspOptions |= QBSP_NOTEXTURES;
  90.       
  91.       fclose(bspFile);
  92.       if (!(bspFile = fopen(bspName, WRITE_BINARY))) {
  93.         eprintf("failed to re-open file %s\n", bspName);
  94.         break;
  95.       }
  96.     }
  97.     else {
  98.       if (!(bspFile = fopen(bspName, WRITE_BINARY))) {
  99.         eprintf("failed to open new file %s\n", bspName);
  100.         break;
  101.       }
  102.       if (!(bspMem = (struct memory *)tmalloc(sizeof(struct memory)))) {
  103.         eprintf("failed to allocate bspMem\n");
  104.         break;
  105.       }
  106.  
  107.       // init the tables to be shared by all models
  108.       BeginBSPFile(bspMem);
  109.       bspMem->mapOptions |= ((newLit == TRUE) ? MAP_LOADLIGHTS : 0);
  110.       bspMem->bspOptions |= ((watervis == TRUE) ? QBSP_WATERVIS : 0);
  111.       bspMem->bspOptions |= ((slimevis == TRUE) ? QBSP_SLIMEVIS : 0);
  112.       bspMem->bspOptions |= ((nofill == TRUE) ? QBSP_NOFILL : 0);
  113.       bspMem->bspOptions |= ((notjunc == TRUE) ? QBSP_NOTJUNC : 0);
  114.       bspMem->bspOptions |= ((noclip == TRUE) ? QBSP_NOCLIP : 0);
  115.       bspMem->bspOptions |= ((onlyents == TRUE) ? QBSP_ONLYENTS : 0);
  116.       bspMem->bspOptions |= ((usehulls == TRUE) ? QBSP_USEHULLS : 0);
  117.  
  118.       // load brushes and bspMem->mapentities
  119.       if (inType == TYPE_IMAGINE) {
  120.         if((retval = LoadTDDDFile(bspMem, inData->rawdata)) == FALSE) {
  121.           eprintf("failed to load TDDD\n");
  122.           break;
  123.         }
  124.       }
  125.       else if (inType == TYPE_MAP) {
  126.         if ((retval = LoadMapFile(bspMem, inData->rawdata)) == FALSE) {
  127.           eprintf("failed to load map\n");
  128.           break;
  129.         }
  130.       }
  131.       if ((retval = qbsp(bspMem, hullnum, subdivide, bspName)) == FALSE) {
  132.         eprintf("failed to calculate bsp-tree\n");
  133.         break;
  134.       }
  135.     }
  136.  
  137.     bspMem->litOptions |= ((newLit == TRUE) ? LIGHT_MEM : 0);
  138.     bspMem->litOptions |= ((waterlit == TRUE) ? LIGHT_WATERLIT : 0);
  139.     bspMem->visOptions |= ((fastvis == TRUE) ? VIS_FAST : 0);
  140.     bspMem->visOptions |= ((verbose == TRUE) ? VIS_VERBOSE : 0);
  141.    
  142.     if (newVis == TRUE) {
  143.       mprintf("build vis-data\n");
  144.       if ((retval = vis(bspMem, vislevel, inData->rawdata)) == FALSE) {
  145.         eprintf("failed to calculate vis-data\n");
  146.         break;
  147.       }
  148.     }
  149.     else if(oldVis == TRUE) {
  150.       mprintf("replace vis-data\n");
  151.       FreeClusters(bspMem, LUMP_VISIBILITY);
  152.       bspMem->dvisdata = inData->rawdata;
  153.       bspMem->visdatasize = inData->size;
  154.       WriteBSP(bspFile, bspMem);
  155.       retval = TRUE;
  156.       break;
  157.     }
  158.     
  159.     if (newLit == TRUE) {
  160.       mprintf("build lit-data\n");
  161.       if ((retval = light(bspMem, scale, range)) == FALSE) {
  162.         eprintf("failed to calculate lit-data\n");
  163.         break;
  164.       }
  165.     }
  166.     else if(oldLit == TRUE) {
  167.       mprintf("replace lit-data\n");
  168.       FreeClusters(bspMem, LUMP_LIGHTING);
  169.       bspMem->dlightdata = inData->rawdata;
  170.       bspMem->lightdatasize = inData->size;
  171.       WriteBSP(bspFile, bspMem);
  172.       retval = TRUE;
  173.       break;
  174.     }
  175.  
  176.     FinishBSPFile(bspMem, bspFile);
  177.     retval = TRUE;
  178.       }
  179.       break;
  180.     }
  181.   }
  182.   if (bspFile)
  183.     fclose(bspFile);
  184.   if (bspMem) {
  185.     FreeClusters(bspMem, 0);
  186.     tfree(bspMem);
  187.   }
  188.  
  189. #ifdef    MEM_SIZETRACK
  190.   mprintf(" memory  :        %7i (       %7i)\n", memcounter, mempeak);
  191. #ifdef    MEM_ANALYSE
  192.   mprintf("                  %7i (       %7i)\n", memallocs, mempeakallocs);
  193.   mprintf("                  %7i (       %7i)\n", memcounter/memallocs, mempeak/mempeakallocs);
  194. #endif
  195. #endif
  196.   return retval;
  197. }
  198.  
  199. /*
  200.  * BSP-tools
  201.  * destDir == 0 -> OP_EXTRACT to current directory
  202.  */
  203. bool ExtractBSP(FILE * bspFile, FILE * script, char *destDir, char *entryName, filetype outType, operation procOper, bool recurse)
  204. {
  205.   FILE *outFile;
  206.   bool retval = FALSE;
  207.   __memBase = 0;
  208.  
  209. #ifdef    PRINTCALLS
  210.   mprintf("ExtractBSP(%lx, %lx, %s, %s, %d, %d, %d)\n", bspFile, script, destDir, entryName, outType, procOper, recurse);
  211. #endif
  212.  
  213.   if (!setjmp(eabort)) {
  214.     if ((bspMem = LoadBSP(bspFile, LUMP_TEXTURES                   // BSPtoMap/BSPtoWAD/BSPtoMip
  215.                | LUMP_ENTITIES                       // BSPtoMap
  216.                | LUMP_PLANES                       // BSPtoMap
  217.                | LUMP_FACES                           // BSPtoMap
  218.                | LUMP_EDGES                           // GetEdges
  219.                | LUMP_SURFEDGES                       // GetEdges
  220.                | LUMP_MODELS                       // BSPtoMap
  221.                | LUMP_VERTEXES                       // BSPtoMap
  222.                | LUMP_TEXINFO                       // BSPtoMap
  223.                | LUMP_VISIBILITY                       // BSPtoVis
  224.                | LUMP_LIGHTING                       // BSPtoLit
  225.      ))) {
  226.       /*
  227.        * save mip-textures 
  228.        */
  229.       int i;
  230.       char destPath[NAMELEN_PATH], *destName;
  231.       bool toWad = FALSE;
  232.       bool toMap = FALSE;
  233.       bool toVis = FALSE;
  234.       bool toLit = FALSE;
  235.       bool toIob = FALSE;
  236.  
  237.       strncpy(destPath, destDir, NAMELEN_PATH - 1);
  238.       if (!entryName) {
  239.         destName = smalloc(destDir);
  240.         destName[strlen(destName) - 1] = '\0';
  241.         if (outType == TYPE_WAD2)           toWad = TRUE;
  242.         else if (outType == TYPE_MAP)       toMap = TRUE;
  243.         else if (outType == TYPE_IMAGINE) toMap = toIob = TRUE;
  244.         else if (outType == TYPE_VIS)       toVis = TRUE;
  245.         else if (outType == TYPE_LIT)      toLit = TRUE;
  246.         else                  toWad = toMap = toVis = toLit = TRUE;    /* default: extract all */
  247.         strncat(destPath, GetFile(destName), NAMELEN_PATH - 1);
  248.         tfree(destName);
  249.       }
  250.       else {
  251.         destName = GetExt(entryName);
  252.         strncat(destPath, GetFile(entryName), NAMELEN_PATH - 1);
  253.         if (!strcmp(destName, "wad") || (outType == TYPE_WAD2))            { entryName = 0; toWad = TRUE; }
  254.         else if (!strcmp(destName, "map") || (outType == TYPE_MAP))     { entryName = 0; toMap = TRUE; }
  255.         else if (!strcmp(destName, "iob") || (outType == TYPE_IMAGINE)) { entryName = 0; toMap = toIob = TRUE; }
  256.         else if (!strcmp(destName, "vis") || (outType == TYPE_VIS))     { entryName = 0; toVis = TRUE; }
  257.         else if (!strcmp(destName, "lit") || (outType == TYPE_LIT))     { entryName = 0; toLit = TRUE; }
  258.       }
  259.  
  260.       if (procOper == OP_EXTRACT)
  261.         CreatePath(destPath);
  262.  
  263.       if (bspMem->dtexdata) {
  264.     int *MipOffsets = (int *)bspMem->dtexdata;
  265.     int MipNums = *MipOffsets++;
  266.  
  267.     /*
  268.      * decode mips from bsp
  269.      */
  270.     ReplaceExt(destPath, "wad");
  271.     for (i = 0; i < MipNums; i++) {
  272.       struct mipmap *Texture = (struct mipmap *)(MipOffsets[i] + bspMem->dtexdata);
  273.  
  274.       if (!(entryName && strncmp(entryName, Texture->name, NAMELEN_MIP))) {
  275.         char fileName[NAMELEN_PATH];
  276.  
  277.         strncpy(fileName, destDir, NAMELEN_PATH - 1);
  278.         strncat(fileName, Texture->name, NAMELEN_PATH - 1);
  279.  
  280.         switch (outType) {
  281.           case TYPE_PPM:    strncat(fileName, ".ppm", NAMELEN_PATH - 1); break;
  282.           case TYPE_JPEG:    strncat(fileName, ".jpg", NAMELEN_PATH - 1); break;
  283.           case TYPE_ILBM:    strncat(fileName, ".iff", NAMELEN_PATH - 1); break;
  284.           case TYPE_PNG:    strncat(fileName, ".png", NAMELEN_PATH - 1); break;
  285.           case TYPE_NONE:
  286.           default:        strncat(fileName, ".mip", NAMELEN_PATH - 1); break;
  287.         }
  288.  
  289.         switch (procOper) {
  290.           case OP_EXTRACT:{
  291.           struct palpic *MipMap;
  292.  
  293.           if ((MipMap = ParseMipMap(Texture, MIPMAP_0))) {
  294.             if (toWad == TRUE) {
  295.               mprintf("extract %s to wad %s\n", MipMap->name, destPath);
  296.               AddWAD2(MipMap, 0, destPath, OP_UPDATE, WAD2_MIPMAP);
  297.             }
  298.             else {
  299.               FILE *fileDst;
  300.  
  301.               mprintf("extract %s to %s ...\n", MipMap->name, fileName);
  302.               CreatePath(fileName);
  303.  
  304.               if ((fileDst = fopen(fileName, WRITE_BINARY))) {
  305.             if (outType != TYPE_NONE)
  306.               retval = PutImage(fileDst, MipMap, outType);
  307.             else
  308.               retval = PutMipMap(fileDst, MipMap);
  309.             fclose(fileDst);
  310.               }
  311.               else
  312.             eprintf("cannot open %s\n", fileName);
  313.             }
  314.             pfree(MipMap);
  315.           }
  316.           else
  317.             eprintf("cannot read mipmap %s\n", MipMap->name);
  318.         }
  319.         break;
  320.           case OP_LIST:
  321.           case OP_DEFAULT:
  322.           default:{
  323.           mprintf("%16s (offset: %8d)\n", Texture->name, MipOffsets[i]);
  324.           retval = TRUE;
  325.         }
  326.         break;
  327.         }
  328.         if (script)
  329.           fprintf(script, "update %s as %s as %c\n", fileName, Texture->name, WAD2_MIPMAP);
  330.       }
  331.     }
  332.     if ((toWad == TRUE) && (recurse == TRUE))
  333.       retval = processName(destPath, 0, 0, outType, 0, 0, procOper, script ? TRUE : FALSE, recurse);
  334.       }
  335.  
  336.       if ((bspMem->dentdata) && (toMap == TRUE)) {
  337.     /*
  338.      * decode map from bsp
  339.      */
  340.     LoadMapFile(bspMem, bspMem->dentdata);
  341.     if (procOper == OP_EXTRACT) {
  342.       ReplaceExt(destPath, toIob == TRUE ? "iob" : "map");
  343.  
  344.       if ((outFile = fopen(destPath, toIob == TRUE ? WRITE_BINARY : "w"))) {
  345.         LoadBSPFile(bspMem);
  346.  
  347.         if(toIob == TRUE)
  348.           SaveTDDDFile(bspMem, outFile);
  349.         else
  350.           SaveMapFile(bspMem, outFile);
  351.  
  352.         fclose(outFile);
  353.       }
  354.     }
  355.     retval = TRUE;
  356.       }
  357.  
  358.       if ((bspMem->dvisdata) && (toVis == TRUE) && (procOper == OP_EXTRACT)) {
  359.     /*
  360.      * decode vis from bsp
  361.      */
  362.     ReplaceExt(destPath, "vis");
  363.     if ((outFile = fopen(destPath, WRITE_BINARY))) {
  364.       fwrite((void *)bspMem->dvisdata, 1, bspMem->visdatasize * sizeof(unsigned char), outFile);
  365.       fclose(outFile);
  366.       retval = TRUE;
  367.     }
  368.       }
  369.  
  370.       if ((bspMem->dlightdata) && (toLit == TRUE) && (procOper == OP_EXTRACT)) {
  371.     /*
  372.      * decode lit from bsp
  373.      */
  374.     ReplaceExt(destPath, "lit");
  375.     if ((outFile = fopen(destPath, WRITE_BINARY))) {
  376.       fwrite((void *)bspMem->dlightdata, 1, bspMem->lightdatasize * sizeof(unsigned char), outFile);
  377.       fclose(outFile);
  378.       retval = TRUE;
  379.     }
  380.       }
  381.  
  382.       if ((procOper == OP_LIST) || (procOper == OP_DEFAULT))
  383.     PrintClusters(bspMem, 0, FALSE);
  384.       FreeClusters(bspMem, 0);
  385.     }
  386.     else
  387.       eprintf("cannot read bspfile\n");
  388.   }
  389.  
  390.   /*
  391.    * outstanding:
  392.    *  scripting for bsps
  393.    *  maptotri/iob?
  394.    */
  395.  
  396.   return retval;
  397. }
  398.  
  399. /*
  400.  * =============
  401.  * SwapBSPFile
  402.  * 
  403.  * Byte swaps all data in a bsp file.
  404.  * =============
  405.  */
  406. void SwapBSPFile(__memBase, bool toDisk)
  407. {
  408.   int i, c;
  409.   short int j;
  410.   struct dmodel_t *d;
  411.   struct dmiptexlump_t *mtl;
  412.  
  413.   /*
  414.    * planes
  415.    */
  416.   if (bspMem->availHeaders & LUMP_PLANES)
  417.     for (i = 0; i < bspMem->numplanes; i++) {
  418.       for (j = 0; j < 3; j++)
  419.     bspMem->dplanes[i].normal[j] = LittleFloat(bspMem->dplanes[i].normal[j]);
  420.       bspMem->dplanes[i].dist = LittleFloat(bspMem->dplanes[i].dist);
  421.       bspMem->dplanes[i].type = LittleLong(bspMem->dplanes[i].type);
  422.     }
  423.  
  424.   /*
  425.    * miptex
  426.    */
  427.   if (bspMem->availHeaders & LUMP_TEXTURES)
  428.     if (bspMem->texdatasize) {
  429.       mtl = (struct dmiptexlump_t *)bspMem->dtexdata;
  430.       if (toDisk == TRUE)
  431.     c = mtl->nummiptex;
  432.       else
  433.     c = LittleLong(mtl->nummiptex);
  434.       mtl->nummiptex = LittleLong(mtl->nummiptex);
  435.       for (i = 0; i < c; i++)
  436.     mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
  437.     }
  438.  
  439.   /*
  440.    * vertexes
  441.    */
  442.   if (bspMem->availHeaders & LUMP_VERTEXES)
  443.     for (i = 0; i < bspMem->numvertexes; i++) {
  444.       for (j = 0; j < 3; j++)
  445.     bspMem->dvertexes[i].point[j] = LittleFloat(bspMem->dvertexes[i].point[j]);
  446.     }
  447.  
  448.   /*
  449.    * nodes
  450.    */
  451.   if (bspMem->availHeaders & LUMP_NODES)
  452.     for (i = 0; i < bspMem->numnodes; i++) {
  453.       bspMem->dnodes[i].planenum = LittleLong(bspMem->dnodes[i].planenum);
  454.       for (j = 0; j < 3; j++) {
  455.     bspMem->dnodes[i].mins[j] = LittleShort(bspMem->dnodes[i].mins[j]);
  456.     bspMem->dnodes[i].maxs[j] = LittleShort(bspMem->dnodes[i].maxs[j]);
  457.       }
  458.       bspMem->dnodes[i].children[0] = LittleShort(bspMem->dnodes[i].children[0]);
  459.       bspMem->dnodes[i].children[1] = LittleShort(bspMem->dnodes[i].children[1]);
  460.       bspMem->dnodes[i].firstface = LittleShort(bspMem->dnodes[i].firstface);
  461.       bspMem->dnodes[i].numfaces = LittleShort(bspMem->dnodes[i].numfaces);
  462.     }
  463.  
  464.   /*
  465.    * texinfos
  466.    */
  467.   if (bspMem->availHeaders & LUMP_TEXINFO)
  468.     for (i = 0; i < bspMem->numtexinfo; i++) {
  469.       for (j = 0; j < 8; j++)
  470.     bspMem->texinfo[i].vecs[0][j] = LittleFloat(bspMem->texinfo[i].vecs[0][j]);
  471.       bspMem->texinfo[i].miptex = LittleLong(bspMem->texinfo[i].miptex);
  472.       bspMem->texinfo[i].flags = LittleLong(bspMem->texinfo[i].flags);
  473.     }
  474.  
  475.   /*
  476.    * faces
  477.    */
  478.   if (bspMem->availHeaders & LUMP_FACES)
  479.     for (i = 0; i < bspMem->numfaces; i++) {
  480.       bspMem->dfaces[i].texinfo = LittleShort(bspMem->dfaces[i].texinfo);
  481.       bspMem->dfaces[i].planenum = LittleShort(bspMem->dfaces[i].planenum);
  482.       bspMem->dfaces[i].side = LittleShort(bspMem->dfaces[i].side);
  483.       bspMem->dfaces[i].lightofs = LittleLong(bspMem->dfaces[i].lightofs);
  484.       bspMem->dfaces[i].firstedge = LittleLong(bspMem->dfaces[i].firstedge);
  485.       bspMem->dfaces[i].numedges = LittleShort(bspMem->dfaces[i].numedges);
  486.     }
  487.  
  488.   /*
  489.    * clipnodes
  490.    */
  491.   if (bspMem->availHeaders & LUMP_CLIPNODES)
  492.     for (i = 0; i < bspMem->numclipnodes; i++) {
  493.       bspMem->dclipnodes[i].planenum = LittleLong(bspMem->dclipnodes[i].planenum);
  494.       bspMem->dclipnodes[i].children[0] = LittleShort(bspMem->dclipnodes[i].children[0]);
  495.       bspMem->dclipnodes[i].children[1] = LittleShort(bspMem->dclipnodes[i].children[1]);
  496.     }
  497.  
  498.   /*
  499.    * leafs
  500.    */
  501.   if (bspMem->availHeaders & LUMP_LEAFS)
  502.     for (i = 0; i < bspMem->numleafs; i++) {
  503.       bspMem->dleafs[i].contents = LittleLong(bspMem->dleafs[i].contents);
  504.       for (j = 0; j < 3; j++) {
  505.     bspMem->dleafs[i].mins[j] = LittleShort(bspMem->dleafs[i].mins[j]);
  506.     bspMem->dleafs[i].maxs[j] = LittleShort(bspMem->dleafs[i].maxs[j]);
  507.       }
  508.       bspMem->dleafs[i].firstmarksurface = LittleShort(bspMem->dleafs[i].firstmarksurface);
  509.       bspMem->dleafs[i].nummarksurfaces = LittleShort(bspMem->dleafs[i].nummarksurfaces);
  510.       bspMem->dleafs[i].visofs = LittleLong(bspMem->dleafs[i].visofs);
  511.     }
  512.  
  513.   /*
  514.    * marksurfaces
  515.    */
  516.   if (bspMem->availHeaders & LUMP_MARKSURFACES)
  517.     for (i = 0; i < bspMem->nummarksurfaces; i++)
  518.       bspMem->dmarksurfaces[i] = LittleShort(bspMem->dmarksurfaces[i]);
  519.  
  520.   /*
  521.    * edges
  522.    */
  523.   if (bspMem->availHeaders & LUMP_EDGES)
  524.     for (i = 0; i < bspMem->numedges; i++) {
  525.       bspMem->dedges[i].v[0] = LittleShort(bspMem->dedges[i].v[0]);
  526.       bspMem->dedges[i].v[1] = LittleShort(bspMem->dedges[i].v[1]);
  527.     }
  528.  
  529.   /*
  530.    * surfedges
  531.    */
  532.   if (bspMem->availHeaders & LUMP_SURFEDGES)
  533.     for (i = 0; i < bspMem->numsurfedges; i++)
  534.       bspMem->dsurfedges[i] = LittleLong(bspMem->dsurfedges[i]);
  535.  
  536.   /*
  537.    * models
  538.    */
  539.   if (bspMem->availHeaders & LUMP_MODELS)
  540.     for (i = 0; i < bspMem->nummodels; i++) {
  541.       d = &bspMem->dmodels[i];
  542.       for (j = 0; j < MAX_MAP_HULLS; j++)
  543.     d->headnode[j] = LittleLong(d->headnode[j]);
  544.       d->visleafs = LittleLong(d->visleafs);
  545.       d->firstface = LittleLong(d->firstface);
  546.       d->numfaces = LittleLong(d->numfaces);
  547.       for (j = 0; j < 3; j++) {
  548.     d->mins[j] = LittleFloat(d->mins[j]);
  549.     d->maxs[j] = LittleFloat(d->maxs[j]);
  550.     d->origin[j] = LittleFloat(d->origin[j]);
  551.       }
  552.     }
  553. }
  554.  
  555. int GetBlock(register FILE *bspFile, register struct dpair *dPair, register void **store, register int partSize)
  556. {
  557.   register int blockSize = LittleLong(dPair->size);
  558.  
  559.   if ((*store = (void *)tmalloc(blockSize))) {
  560.     fseek(bspFile, LittleLong(dPair->offset), SEEK_SET);
  561.     fread(*store, 1, blockSize, bspFile);
  562.     return (blockSize / partSize);
  563.   }
  564.   else
  565.     return 0;
  566. }
  567.  
  568. void PutBlock(register FILE *bspFile, register struct dpair *dPair, register void *store, register int blockSize)
  569. {
  570.   if (blockSize) {
  571.     dPair->size = LittleLong(blockSize);
  572.     dPair->offset = LittleLong(ftell(bspFile));
  573.     fwrite(store, 1, (blockSize + 3) & ~3, bspFile);
  574.     /*
  575.      * probably we want to use it after this
  576.      * tfree(store);
  577.      */
  578.   }
  579.   else {
  580.     dPair->size = 0;
  581.     dPair->offset = LittleLong(ftell(bspFile));
  582.   }
  583. }
  584.  
  585. /*
  586.  * =============
  587.  * LoadBSPFile
  588.  * =============
  589.  */
  590. struct memory *LoadBSP(FILE * bspFile, int availLoad)
  591. {
  592.   __memBase = 0;
  593.  
  594.   if ((bspMem = (struct memory *)tmalloc(sizeof(struct memory)))) {
  595.     struct bspheader Header;
  596.     memset(&Header, 0, sizeof(struct bspheader));
  597.     memset(bspMem, 0, sizeof(struct memory));
  598.  
  599.     /*
  600.      * load the file header
  601.      */
  602.     fseek(bspFile, 0, SEEK_SET);
  603.     fread(&Header, 1, sizeof(struct bspheader), bspFile);
  604.  
  605.     if (Header.version == LittleLong(BSP_VERSION)) {
  606.       bspMem->availHeaders = availLoad;
  607.  
  608.       if (availLoad & LUMP_ENTITIES)
  609.     bspMem->entdatasize = bspMem->max_entdatasize = GetBlock(bspFile, &Header.entities, (void **)&bspMem->dentdata, sizeof(char));
  610.  
  611.       if (availLoad & LUMP_PLANES)
  612.     bspMem->numplanes = bspMem->max_numplanes = GetBlock(bspFile, &Header.planes, (void **)&bspMem->dplanes, sizeof(struct dplane_t));
  613.  
  614.       if (availLoad & LUMP_TEXTURES)
  615.     bspMem->texdatasize = bspMem->max_texdatasize = GetBlock(bspFile, &Header.miptex, (void **)&bspMem->dtexdata, sizeof(unsigned char));
  616.  
  617.       if (availLoad & LUMP_VERTEXES)
  618.     bspMem->numvertexes = bspMem->max_numvertexes = GetBlock(bspFile, &Header.vertices, (void **)&bspMem->dvertexes, sizeof(struct dvertex_t));
  619.  
  620.       if (availLoad & LUMP_VISIBILITY)
  621.     bspMem->visdatasize = bspMem->max_visdatasize = GetBlock(bspFile, &Header.visilist, (void **)&bspMem->dvisdata, sizeof(unsigned char));
  622.  
  623.       if (availLoad & LUMP_NODES)
  624.     bspMem->numnodes = bspMem->max_numnodes = GetBlock(bspFile, &Header.nodes, (void **)&bspMem->dnodes, sizeof(struct dnode_t));
  625.  
  626.       if (availLoad & LUMP_TEXINFO)
  627.     bspMem->numtexinfo = bspMem->max_numtexinfo = GetBlock(bspFile, &Header.texinfo, (void **)&bspMem->texinfo, sizeof(struct texinfo));
  628.  
  629.       if (availLoad & LUMP_FACES)
  630.     bspMem->numfaces = bspMem->max_numfaces = GetBlock(bspFile, &Header.faces, (void **)&bspMem->dfaces, sizeof(struct dface_t));
  631.  
  632.       if (availLoad & LUMP_LIGHTING)
  633.     bspMem->lightdatasize = bspMem->max_lightdatasize = GetBlock(bspFile, &Header.lightmaps, (void **)&bspMem->dlightdata, sizeof(unsigned char));
  634.  
  635.       if (availLoad & LUMP_CLIPNODES)
  636.     bspMem->numclipnodes = bspMem->max_numclipnodes = GetBlock(bspFile, &Header.clipnodes, (void **)&bspMem->dclipnodes, sizeof(struct dclipnode_t));
  637.  
  638.       if (availLoad & LUMP_LEAFS)
  639.     bspMem->numleafs = bspMem->max_numleafs = GetBlock(bspFile, &Header.leaves, (void **)&bspMem->dleafs, sizeof(struct dleaf_t));
  640.  
  641.       if (availLoad & LUMP_MARKSURFACES)
  642.     bspMem->nummarksurfaces = bspMem->max_nummarksurfaces = GetBlock(bspFile, &Header.lface, (void **)&bspMem->dmarksurfaces, sizeof(unsigned short int));
  643.  
  644.       if (availLoad & LUMP_EDGES)
  645.     bspMem->numedges = bspMem->max_numedges = GetBlock(bspFile, &Header.edges, (void **)&bspMem->dedges, sizeof(struct dedge_t));
  646.  
  647.       if (availLoad & LUMP_SURFEDGES)
  648.     bspMem->numsurfedges = bspMem->max_numsurfedges = GetBlock(bspFile, &Header.ledges, (void **)&bspMem->dsurfedges, sizeof(int));
  649.  
  650.       if (availLoad & LUMP_MODELS)
  651.     bspMem->nummodels = bspMem->max_nummodels = GetBlock(bspFile, &Header.models, (void **)&bspMem->dmodels, sizeof(struct dmodel_t));
  652.  
  653.       /*
  654.        * swap everything
  655.        */
  656.       SwapBSPFile(bspMem, FALSE);
  657.     }
  658.     else {
  659.       tfree(bspMem);
  660.       bspMem = 0;
  661.       eprintf("no valid bsp-file\n");
  662.     }
  663.   }
  664.  
  665.   return bspMem;
  666. }
  667.  
  668. /*
  669.  * =============
  670.  * WriteBSPFile
  671.  * =============
  672.  */
  673. void WriteBSP(FILE * bspFile, __memBase)
  674. {
  675.   if (bspMem) {
  676.     struct bspheader Header;
  677.     memset(&Header, 0, sizeof(struct bspheader));
  678.  
  679.     Header.version = LittleLong(BSP_VERSION);
  680.  
  681.     /*
  682.      * save the file header
  683.      */
  684.     fseek(bspFile, 0, SEEK_SET);
  685.     fwrite(&Header, 1, sizeof(struct bspheader), bspFile);
  686.  
  687.     /*
  688.      * swap everything
  689.      */
  690.     SwapBSPFile(bspMem, TRUE);
  691.  
  692.     if (bspMem->availHeaders & LUMP_PLANES)
  693.       PutBlock(bspFile, &Header.planes, (void *)bspMem->dplanes, bspMem->numplanes * sizeof(struct dplane_t));
  694.  
  695.     if (bspMem->availHeaders & LUMP_LEAFS)
  696.       PutBlock(bspFile, &Header.leaves, (void *)bspMem->dleafs, bspMem->numleafs * sizeof(struct dleaf_t));
  697.  
  698.     if (bspMem->availHeaders & LUMP_VERTEXES)
  699.       PutBlock(bspFile, &Header.vertices, (void *)bspMem->dvertexes, bspMem->numvertexes * sizeof(struct dvertex_t));
  700.  
  701.     if (bspMem->availHeaders & LUMP_NODES)
  702.       PutBlock(bspFile, &Header.nodes, (void *)bspMem->dnodes, bspMem->numnodes * sizeof(struct dnode_t));
  703.  
  704.     if (bspMem->availHeaders & LUMP_TEXINFO)
  705.       PutBlock(bspFile, &Header.texinfo, (void *)bspMem->texinfo, bspMem->numtexinfo * sizeof(struct texinfo));
  706.  
  707.     if (bspMem->availHeaders & LUMP_FACES)
  708.       PutBlock(bspFile, &Header.faces, (void *)bspMem->dfaces, bspMem->numfaces * sizeof(struct dface_t));
  709.  
  710.     if (bspMem->availHeaders & LUMP_CLIPNODES)
  711.       PutBlock(bspFile, &Header.clipnodes, (void *)bspMem->dclipnodes, bspMem->numclipnodes * sizeof(struct dclipnode_t));
  712.  
  713.     if (bspMem->availHeaders & LUMP_MARKSURFACES)
  714.       PutBlock(bspFile, &Header.lface, (void *)bspMem->dmarksurfaces, bspMem->nummarksurfaces * sizeof(unsigned short int));
  715.  
  716.     if (bspMem->availHeaders & LUMP_SURFEDGES)
  717.       PutBlock(bspFile, &Header.ledges, (void *)bspMem->dsurfedges, bspMem->numsurfedges * sizeof(int));
  718.  
  719.     if (bspMem->availHeaders & LUMP_EDGES)
  720.       PutBlock(bspFile, &Header.edges, (void *)bspMem->dedges, bspMem->numedges * sizeof(struct dedge_t));
  721.  
  722.     if (bspMem->availHeaders & LUMP_MODELS)
  723.       PutBlock(bspFile, &Header.models, (void *)bspMem->dmodels, bspMem->nummodels * sizeof(struct dmodel_t));
  724.  
  725.     if (bspMem->availHeaders & LUMP_LIGHTING)
  726.       PutBlock(bspFile, &Header.lightmaps, (void *)bspMem->dlightdata, bspMem->lightdatasize * sizeof(unsigned char));
  727.  
  728.     if (bspMem->availHeaders & LUMP_VISIBILITY)
  729.       PutBlock(bspFile, &Header.visilist, (void *)bspMem->dvisdata, bspMem->visdatasize * sizeof(unsigned char));
  730.  
  731.     if (bspMem->availHeaders & LUMP_ENTITIES)
  732.       PutBlock(bspFile, &Header.entities, (void *)bspMem->dentdata, bspMem->entdatasize * sizeof(char));
  733.  
  734.     if (bspMem->availHeaders & LUMP_TEXTURES)
  735.       PutBlock(bspFile, &Header.miptex, (void *)bspMem->dtexdata, bspMem->texdatasize * sizeof(unsigned char));
  736.  
  737.     /*
  738.      * save the file header
  739.      */
  740.     fseek(bspFile, 0, SEEK_SET);
  741.     fwrite(&Header, 1, sizeof(struct bspheader), bspFile);
  742.  
  743.     /*
  744.      * tfree(bspMem); 
  745.      */
  746.   }
  747. }
  748.